<?php


namespace app\controller\api;


use app\BaseController;
use app\common\exception\ApiException;
use app\model\config\BannerModel;
use app\model\config\RegionModel;
use app\model\goods\OrderModel;
use app\model\partner\EscortMenuModel;
use app\model\partner\EscortMenuOrderLogModel;
use app\model\partner\EscortMenuOrderModel;
use app\model\partner\EscortMenuReserveOrderModel;
use app\model\partner\OrderLogModel;
use app\model\partner\PartnerBusyTimeModel;
use app\model\partner\PartnerCityModel;
use app\model\partner\UserPartnerAreaModel;
use app\model\partner\UserPartnerModel;
use app\model\user\UserCouponModel;
use app\model\user\UserCourseModel;
use app\model\user\UserEvaluateModel;
use app\model\user\UserExamineModel;
use app\model\user\UserExamineRecordModel;
use app\model\user\UserModel;
use app\service\config\ConfigService;
use app\service\order\PartnerOrderService;
use app\service\user\PartnerMoneyRecordService;
use app\service\user\UserCouponService;
use app\service\user\UserService;
use app\service\utils\LockService;
use app\service\utils\QqMapService;
use app\service\utils\WeiXinOfficialService;
use app\service\utils\WeiXinPayService;
use app\validate\cart\PartnerDriveValidate;
use GuzzleHttp\Exception\GuzzleException;
use think\facade\Db;
use think\facade\Log;
use think\facade\Queue;

class PartnerDriveController extends BaseController
{
    /**
     * 陪驾轮播图
     * @return \think\response\Json
     */
    public function banner()
    {
        try {
            $list = BannerModel::order('sort', 'desc')->where('poisition', 2)->field('img,content,type')->select();
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 开通城市
     * @return \think\response\Json
     */
    public function getOpenCityArr()
    {
        try {
            $list = PartnerCityModel::order('sort', 'desc')->select();
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 陪驾套餐列表
     * @return \think\response\Json
     */
    public function getEscortMenuList()
    {
        try {
            $page = $this->request->param('page', 1, 'int');
            $limit = $this->request->param('limit', 10, 'int');
            $cityId = $this->request->param('city_id', 410100, 'trim');
            $list = EscortMenuModel::where('status', 1)
                ->where('city_id', 'like', '%' . $cityId . '%')
                ->field('id,image,name,min,price,old_price,day,create_time,sale_num')
                ->order('sort', 'desc')
                ->paginate(['list_row' => $limit, 'page' => $page])
                ->toArray();
            foreach ($list['data'] as &$val) {
                $val['end_time'] = date('Y-m-d', strtotime($val['create_time']) + $val['day'] * 86400);
//                $val['sale_num'] = EscortMenuOrderModel::where('menu_id', $val['id'])->whereIn('pay_status', [2, 3])->count();
            }
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 陪驾套餐详情
     * @return \think\response\Json
     */
    public function getEscortMenuInfo()
    {
        try {
            $id = $this->request->param('id');
            $info = EscortMenuModel::find($id);
            if (!$info) {
                throw new ApiException('套餐不存在');
            }
//            $info['sale_num'] = EscortMenuOrderModel::where('menu_id', $info['id'])->whereIn('pay_status', [2, 3])->count();
            return $this->success($info);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     *订单可用优惠券
     * @return \think\response\Json
     */
    public function getPartnerDriveOrderCouponList()
    {
        try {
            $userId = $this->request->middleware('userId');
            $orderSn = $this->request->param('order_sn', '', 'trim');
            $orderInfo = EscortMenuOrderModel::where('order_sn', $orderSn)->find();
            if (!$orderInfo) {
                throw new ApiException('订单不存在');
            }
            if ($orderInfo['user_id'] != $userId) {
                throw new ApiException('非法请求');
            }
            $userCouponService = new UserCouponService();
            $list = $userCouponService->getOrderCouponList($userId, $orderInfo['amount'], 3);
            return $this->success(['total' => count($list), 'list' => $list]);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 陪驾订单
     * @return \think\response\Json
     */
    public function createEscortMenuOrder()
    {
        try {
            $userId = $this->request->middleware('userId');
            $id = $this->request->param('id', 0);
            $num = $this->request->param('num', 1, 'int');
            $userCityId = $this->request->param('user_city_id', 0, 'trim');
            if ($userCityId <= 0) {
                throw new ApiException('请选择城市');
            }
            if ($num < 1) {
                throw new ApiException('数量错误');
            }

            $info = EscortMenuModel::find($id);
            if (!$info) {
                throw new ApiException('信息不存在');
            }
            if ($info['is_trial'] == 1) {
                $count = EscortMenuOrderModel::where('user_id', $userId)->where('pay_status', 'in', [2, 3])->count();
                if ($count) {
                    throw new ApiException('体验课只能购买一次');
                }
            }

            $orderAmount = bcmul($num, $info['price'], 2);

            $orderSn = createOrderSn('escort_menu_order', 'order_sn', 'TC');

            $escortMenuOrderModel = new EscortMenuOrderModel();
            $escortMenuOrderModel->user_id = $userId;
            $escortMenuOrderModel->menu_id = $id;
            $escortMenuOrderModel->city_id = $info['city_id'];
            $escortMenuOrderModel->order_sn = $orderSn;
            $escortMenuOrderModel->amount = $orderAmount;
            $escortMenuOrderModel->num = $num;
            $escortMenuOrderModel->total = $info['total'] * $num;
            $escortMenuOrderModel->residue_duration = $info['total'] * $num;
            $escortMenuOrderModel->min = $info['min'];
            $escortMenuOrderModel->valid_time = time() + $info['day'] * 86400;
            $escortMenuOrderModel->menu_price = $info['price'];
            $escortMenuOrderModel->menu_old_price = $info['old_price'];
            $escortMenuOrderModel->menu_name = $info['name'];
            $escortMenuOrderModel->menu_image = $info['image'];
            $escortMenuOrderModel->user_city_id = $userCityId;
            $escortMenuOrderModel->save();

            return $this->success(['order_sn' => $orderSn, 'amount' => $orderAmount]);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 订单支付
     * @return \think\response\Json
     */
    public function payPartnerDriveOrder()
    {
        try {
            $userId = $this->request->middleware('userId');
            $orderSn = $this->request->param('order_sn', '', 'trim');
            $userCouponId = $this->request->param('user_coupon_id', 0, 'int');
            $payType = $this->request->param('pay_type', 0, 'int');
            if (!$payType) {
                throw new ApiException('请选择支付类型');
            }
            if (!$orderSn) {
                throw new ApiException('订单号错误');
            }
            $orderInfo = EscortMenuOrderModel::where('order_sn', $orderSn)->find();
            if (!$orderInfo) {
                throw new ApiException('订单不存在');
            }
            if ($orderInfo['user_id'] != $userId) {
                throw new ApiException('非法请求');
            }
            if ($orderInfo['pay_status'] !== 1) {
                throw new ApiException('订单状态错误');
            }
            $userInfo = UserModel::find($orderInfo['user_id']);
            if (!$userInfo) {
                throw new ApiException('用户不存在');
            }
            $openID = $userInfo['openid'];
            if (!$openID) {
                throw new ApiException('用户未授权');
            }
            $couponAmount = 0;
            if ($userCouponId) {
                $couponAmount = UserCouponModel::where('id', $userCouponId)->where('user_id', $userId)->value('amount', 0);
            }
            $payAmount = $orderInfo['amount'] - $couponAmount;
            if ($payAmount <= 0) {
                throw new ApiException('支付金额错误');
            }
            $orderInfo->pay_amount = $payAmount;
            $orderInfo->pay_type = $payType;
            $orderInfo->save();

            if ($payType == 2) {
                throw new ApiException('暂不支持该支付方式');
            }

            $service = new WeiXinPayService();
            $notifyUrl = $this->request->domain() . '/api/notify/partnerDriveNotify';
            $result = $service->pay($orderSn, $payAmount, $openID, $notifyUrl, '陪驾订单支付');
            return $this->success($result);
        } catch (\Exception $exception) {
            return $this->error($exception);
        } catch (GuzzleException $e) {
            return $this->error($e);
        }
    }

    /**
     * 我的套餐
     * @return \think\response\Json
     */
    public function getMyPartnerDriveList()
    {
        try {
            $userId = $this->request->middleware('userId');
            $type = $this->request->param('type', 0, 'int');
            $page = $this->request->param('page', 1, 'int');
            $limit = $this->request->param('limit', 10, 'int');
            $where = [];
            $where[] = ['order_type', '=', 1];
            if ($type) {
                // 查询有时长的订单
                $orderIdArr = EscortMenuOrderModel::where('user_id', $userId)
                    ->where('residue_duration', '>', 0)
                    ->where('pay_status', 2)
                    ->where('valid_time', '>=', time())
                    ->column('id');
                $where[] = ['id', 'in', $orderIdArr];
            } else {
                $where[] = ['user_id', '=', $userId];
                $where[] = ['pay_status', 'in', [2, 3]];
            }
            $menuList = EscortMenuOrderModel::where($where)
                ->order('id', 'desc')
                ->paginate(['list_row' => $limit, 'page' => $page])
                ->toArray();
            foreach ($menuList['data'] as &$v) {
                $v['menu_price'] = $v['pay_amount'] / $v['num'];
                $v['menu_end_time'] = date('Y-m-d', $v['valid_time']);
            }
            return $this->success($menuList);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 预约陪驾
     * @return \think\response\Json
     */
    public function reserve()
    {
        Db::startTrans();
        try {
            $userId = $this->request->middleware('userId');

            $data = $this->request->only(['id', 'partner_id', 'order_id', 'duration', 'time', 'mobile', 'username', 'lng', 'lat', 'address', 'remark'], 'param', 'trim');

            Log::error('预约参数:' . json_encode($data));

            $partnerId = $data['partner_id'] ?? 0;
            $id = $data['id'] ?? 0;
            Validate(PartnerDriveValidate::class)->check($data);

            $orderInfo = EscortMenuOrderModel::find($data['order_id']);
            if (!$orderInfo) {
                throw new ApiException('订单不存在');
            }
            if ($orderInfo['user_id'] != $userId) {
                throw new ApiException('非法请求');
            }

            if ($orderInfo['pay_status'] != 2) {
                throw new ApiException('订单状态错误');
            }
            if ($orderInfo['valid_time'] < time()) {
                throw new ApiException('订单已失效');
            }

            $qqMapService = new QqMapService();
            $info = $qqMapService->getAddressInfo($data['lng'], $data['lat']);
            $adcode = $info['ad_info']['adcode'];
            $regionInfo = RegionModel::where('id', $adcode)->find();
            if (!$regionInfo) {
                throw new ApiException('未找到城市编码');
            }
            if ($regionInfo['level'] == 3) {
                $cityId = $regionInfo['pid'];
            } else {
                $cityId = $adcode;
            }
            if (!in_array($cityId, $orderInfo['city_id'])) {
                throw new ApiException('不支持该城市');
            }

            if (!$id) {
                $orderSn = $orderInfo['order_sn'];

                $userInfo = $this->request->middleware('userInfo');
                $orderModel = new OrderModel();
                $orderModel->order_sn = $orderSn;
                $orderModel->order_type = 0;
                $orderModel->user_id = $userId;
                $orderModel->city_id = $cityId;
                $orderModel->mobile = $data['mobile'] ?: $userInfo['mobile'];
                $orderModel->reserve_time = strtotime($data['time']);
                $orderModel->save();

                $reserveModel = new EscortMenuReserveOrderModel();
                $reserveModel->user_id = $userId;
                $reserveModel->order_sn = $orderSn;
                $reserveModel->order_id = $data['order_id'];
                $reserveModel->is_trial = $orderInfo['is_trial'];
            } else {
                // 减去使用的时长
                $orderInfo->used_duration = Db::raw("used_duration-{$data['duration']}");
                $orderInfo->save();

                $reserveModel = EscortMenuReserveOrderModel::find($id);
                if (!$reserveModel) {
                    throw new ApiException('预约不存在');
                }
            }
            // 预约时长
            $orderDetail = EscortMenuOrderModel::find($data['order_id']);
            if ($data['duration'] < $orderDetail['min']) {
                throw new ApiException('最少预约' . $orderDetail['min'] . '小时');
            }
            $orderResidueDuration = $orderDetail['total'] - $orderDetail['used_duration'];
            if ($orderResidueDuration < $data['duration']) {
                throw new ApiException('剩余时长不足');
            }
            $nextDuration = $orderResidueDuration - $data['duration'];
            if ($nextDuration > 0 && $nextDuration < $orderDetail['min']) {
                throw new ApiException('剩余时长不满足下次使用');
            }


            $orderDetail->used_duration = Db::raw("used_duration+{$data['duration']}");
            $orderDetail->residue_duration = $nextDuration;
            if ($nextDuration == 0) {
                $orderDetail->pay_status = 3;
            }
            $orderDetail->save();

//            $reserveModel->status = EscortMenuReserveOrderModel::WAIT_ASSIGN_ORDER;
            $reserveModel->menu_id = $orderDetail['menu_id'];
            $reserveModel->coach_user_id = $partnerId;
            $reserveModel->duration = $data['duration'];
            $reserveModel->residue_duration = $nextDuration;
            $reserveModel->reserve_time = strtotime($data['time']);
            $reserveModel->reserve_type = $partnerId == 0 ? 1 : 2;
            // 修改订单 不改变订单状态
            if (!$id) {
                $reserveModel->status = $partnerId == 0 ? 1 : 3;
            }
            $reserveModel->username = $data['username'];
            $reserveModel->mobile = $data['mobile'];
            $reserveModel->lng = $data['lng'];
            $reserveModel->lat = $data['lat'];
            $reserveModel->address = $data['address'];
            $reserveModel->remark = $data['remark'];
            $reserveModel->city_id = $cityId;
            $reserveModel->order_type = 1;
            $reserveModel->source_id = 1;
            $reserveModel->save();

            // 套餐使用日志
            $escortMenuOrderLogModel = new EscortMenuOrderLogModel();
            $escortMenuOrderLogModel->order_sn = $orderDetail->order_sn;
            $escortMenuOrderLogModel->total = $orderDetail->total;
            $escortMenuOrderLogModel->used_duration = $orderDetail->used_duration;
            $escortMenuOrderLogModel->residue_duration = $orderDetail->residue_duration;
            $escortMenuOrderLogModel->coach_id = $partnerId;
            $escortMenuOrderLogModel->remark = '用户预约订单';
            $escortMenuOrderLogModel->save();
            Db::commit();

            // 新订单通知
            Queue::push('WeiXinTemplateMsgJob', ['msg_type' => 'new_order', 'id' => $reserveModel->id]);
            return $this->success();
        } catch (\Exception $exception) {
            Db::rollback();
            return $this->error($exception);
        }
    }

    /**
     * 我的预约
     * @return \think\response\Json
     */
    public function getMyPartnerDriveReserveList()
    {
        try {
            $userId = $this->request->middleware('userId');
            // 1待接单 2服务中 3已完成 4已取消
            $type = $this->request->param('type', 0, 'int');
            $where = [];
            $where[] = ['user_id', '=', $userId];
            $where[] = ['order_type', '=', 1];
            if ($type) {
                if ($type == 1) {
                    $where[] = ['status', 'in', [1, 2]];
                }
                if ($type == 2) {
                    $where[] = ['status', 'in', [3, 7, 8]];
                }
                if ($type == 3) {
                    $where[] = ['status', 'in', [4, 5]];
                }
                if ($type == 4) {
                    $where[] = ['status', '=', 6];
                }
            }
            $page = $this->request->param('page', 1, 'int');
            $limit = $this->request->param('limit', 10, 'int');
            $menuList = EscortMenuReserveOrderModel::with(['menuOrder'])
                ->where($where)
                ->order('id', 'desc')
                ->paginate(['list_row' => $limit, 'page' => $page])
                ->toArray();
            foreach ($menuList['data'] as &$value) {
                $value['remark_list'] = OrderLogModel::where('order_id', $value['id'])->select();
            }
            return $this->success($menuList);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 取消预约
     * @return \think\response\Json
     */
    public function cancel()
    {
        Db::startTrans();
        try {
            $userId = $this->request->middleware('userId');
            $id = $this->request->param('id', 0, 'int');
            $info = EscortMenuReserveOrderModel::find($id);
            if (!$info) {
                throw new ApiException('预约信息不存在');
            }
            $info->status = EscortMenuReserveOrderModel::CANCEL;
            $info->cancel_time = time();
            $info->save();

            if ($info['source_id'] == 1) {
                $orderInfo = EscortMenuOrderModel::find($info['order_id']);
                $orderInfo->used_duration = Db::raw("used_duration-{$info['duration']}");
                $orderInfo->residue_duration = Db::raw("residue_duration+{$info['duration']}");
                $orderInfo->pay_status = 2;
                $orderInfo->save();
            } else {
                $orderInfo = EscortMenuOrderModel::find($info['order_id']);
                $orderInfo->pay_status = 4;
                $orderInfo->save();
            }

            // 订单日志 用户取消订单
            $orderLogModel = new OrderLogModel();
            $orderLogModel->order_id = $id;
            $orderLogModel->user_id = $userId;
            $orderLogModel->type = 1;
            $orderLogModel->title = '用户取消订单';
            $orderLogModel->save();

            $orderModel = OrderModel::where('order_sn', $info['order_sn'])->find();
            if ($orderModel) {
                $orderModel->status = -1;
                $orderModel->save();
            }
            // 订单取消通知
            Queue::push('WeiXinTemplateMsgJob', ['msg_type' => 'cancel_order', 'id' => $id]);
            Db::commit();
            return $this->success();
        } catch (\Exception $exception) {
            Db::rollback();
            return $this->error($exception);
        }
    }

    /**
     * 修改预约时间
     * @return \think\response\Json
     */
    public function modifyReserveTime()
    {
        Db::startTrans();
        try {
            $id = $this->request->param('id', 0, 'int');
            $time = $this->request->param('time', '', 'trim');
            $info = EscortMenuReserveOrderModel::find($id);
            if (!$info) {
                throw new ApiException('预约信息不存在');
            }
            if ($info['status'] != 2) {
                throw new ApiException('当前状态不支持修改预约时间');
            }
            $info->reserve_time = strtotime($time);
            $info->save();
            Db::commit();
            return $this->success();
        } catch (\Exception $exception) {
            Db::rollback();
            return $this->error($exception);
        }
    }

    /**
     * 预约详情
     * @return \think\response\Json
     */
    public function getReserveInfo()
    {
        try {
            $id = $this->request->param('id', 0, 'int');
            $info = EscortMenuReserveOrderModel::find($id);
            if (!$info) {
                throw new ApiException('预约信息不存在');
            }
            $userInfo = UserModel::withTrashed()->find($info['user_id']);
            $info['user_name'] = $userInfo['username'];
            $info['user_mobile'] = $userInfo['mobile'];
            $info['user_name'] = $userInfo['username'];

            if ($info['coach_user_id']) {
                $partnerInfo = UserPartnerModel::find($info['coach_user_id']);
                $info['partner_username'] = $partnerInfo['username'];
                $info['partner_avatar'] = $partnerInfo['avatar'];
                $info['partner_age'] = $partnerInfo['age'];
                $info['partner_drive_age'] = $partnerInfo['drive_age'];
                $info['partner_service_num'] = $partnerInfo['service_num'];
                $info['partner_brand'] = $partnerInfo['brand'];
                $info['partner_shap'] = $partnerInfo['shap'];
                $info['partner_gears'] = $partnerInfo['gears'];
                $info['partner_type'] = $partnerInfo['type'];
            }

            $orderInfo = EscortMenuOrderModel::find($info['order_id']);
            $info['menu_end_time'] = date('Y-m-d', $orderInfo['valid_time']);
            $info['menu_min_time'] = $orderInfo['min'];
            $info['menu_residue_time'] = $orderInfo['total'] - $orderInfo['used_duration'];
            $info['pay_type'] = $orderInfo['pay_type'];
            $info['menu_old_price'] = $orderInfo['menu_old_price'];
            $info['menu_price'] = $orderInfo['menu_price'];
            $info['menu_name'] = $orderInfo['menu_name'];
            $info['menu_image'] = $orderInfo['menu_image'];
            return $this->success($info);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 区域列表
     * @return \think\response\Json
     */
    public function getAreaList()
    {
        try {
            $cityId = $this->request->param('city_id', 0, 'int');
            $list = RegionModel::where('pid', $cityId)->select();
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 教练列表
     * @return \think\response\Json
     */
    public function getPartnerList()
    {
        try {
            $search = $this->request->param('search', '', 'trim');
            $cityId = $this->request->param('city_id', 0, 'int');
            $page = $this->request->param('page', 1, 'int');
            $limit = $this->request->param('limit', 10, 'int');
            $areaId = $this->request->param('area_id', 0, 'int');
            $where = [];
            $where [] = ['user_type', 'in', [0, 2]];
            $where [] = ['is_forbid', '=', 0];
            if ($cityId) {
                $where [] = ['city', '=', $cityId];
            }
            if ($areaId) {
                $partnerIdArr = UserPartnerAreaModel::where('area_id', $areaId)->column('user_id');
                $where [] = ['id', 'in', $partnerIdArr];
            }
            if ($search != '') {
                $where [] = ['username|brand|type|shape', 'like', "%$search%"];
            }
            $list = UserPartnerModel::where($where)
                ->field('id,avatar,username,birthday,service_num,brand,shape,type,drive_time')
                ->order('sort', 'desc')
                ->paginate(['list_rows' => $limit, 'page' => $page])
                ->toArray();
            foreach ($list['data'] as &$v) {
                $areaArr = UserPartnerAreaModel::where('user_id', $v['id'])->column('area_id');
                $areaNameArr = RegionModel::whereIn('id', $areaArr)->column('name');
                $v['areas'] = implode(',', $areaNameArr);
            }
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 教练详情
     * @return \think\response\Json
     */
    public function getPartnerDetail()
    {
        try {
            $id = $this->request->param('id', 0, 'int');
            $info = UserPartnerModel::find($id);
            $info->hidden(['status', 'password', 'token', 'token_valid_time', 'delete_time']);
            $info['eval_num'] = UserEvaluateModel::where('type', 0)->where('coach_id', $id)->where('is_del', 0)->count();
            return $this->success($info);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 教练评价列表
     * @return \think\response\Json
     */
    public function getPartnerEvaList()
    {
        try {
            $partnerId = $this->request->param('id', 0, 'int');
            $list = UserEvaluateModel::with('user')
                ->where('coach_id', $partnerId)
                ->where('type', 0)
                ->paginate(['list_row' => $this->limit, 'page' => $this->page])
                ->toArray();
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 教练课程列表
     * @return \think\response\Json
     */
    public function getCoachClassList()
    {
        try {
            $partnerId = $this->request->param('partner_id', 0, 'int');
            $list = UserCourseModel::where('type', 0)
                ->order('sort', 'asc')
                ->select();
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 检测题目列表
     * @return \think\response\Json
     */
    public function getExamineList()
    {
        try {
            $list = UserExamineModel::order('sort', 'asc')->select();
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 提交用户检测
     * @return \think\response\Json
     */
    public function submitUserExamine()
    {
        try {
            $userId = $this->request->middleware('userId');
            $score = $this->request->param('score', 0);

            $userExamineRecordModel = new  UserExamineRecordModel();
            $userExamineRecordModel->user_id = $userId;
            $userExamineRecordModel->score = $score;
            $userExamineRecordModel->save();
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 历史测评
     * @return \think\response\Json
     */
    public function getUserExamineList()
    {
        try {
            $userId = $this->request->middleware('userId');
            $list = UserExamineRecordModel::where('user_id', $userId)->select();
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 上传券码
     * @return \think\response\Json
     */
    public function uploadCode()
    {
        try {
            $orderId = $this->request->param('order_id', 0, 'int');
            $code = $this->request->param('code', '', 'trim');
            $img = $this->request->param('img', '', 'trim');
            if (!$code && !$img) {
                throw new ApiException('请上传券码或图片');
            }
            $escortMenuReserveOrderModel = EscortMenuReserveOrderModel::find($orderId);
            if (!$escortMenuReserveOrderModel) {
                throw new ApiException('订单不存在');
            }
            $escortMenuReserveOrderModel->coupon_code = $code;
            $escortMenuReserveOrderModel->coupon_code_img = $img;
            $escortMenuReserveOrderModel->status = EscortMenuReserveOrderModel::WAIT_CHECK_COUPON;
            $escortMenuReserveOrderModel->save();
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 完成
     * @return \think\response\Json
     */
    public function complete()
    {
        Db::startTrans();
        $orderId = $this->request->param('id', 0, 'int');
        $key = sprintf("complete:partner:%d", $orderId);
        $lockService = new LockService($key);
        $uniqid = uniqid();
        try {
            if (!$lockService->acquireLockWithoutRetry($uniqid)) {
                throw new ApiException('请勿重复完成');
            }
            $partnerOrderService = new PartnerOrderService();
            $partnerOrderService->completeOrderService($orderId);
            Db::commit();
            $lockService->releaseLock($uniqid);
            return $this->success();
        } catch (\Exception $exception) {
            Db::rollback();
            $lockService->releaseLock($uniqid);
            return $this->error($exception);
        }
    }

    /**
     * 评价教练
     * @return \think\response\Json
     */
    public function evaluate()
    {
        try {
            $userId = $this->request->middleware('userId');
            $score = $this->request->param('score', 0, 'int');
            if ($score <= 0) {
                throw new ApiException('请选择评分');
            }
            $coachId = $this->request->param('coach_id', 0, 'int');
            if ($coachId <= 0) {
                throw new ApiException('教练不能为空');
            }
            $anonymity = $this->request->param('anonymity', 0, 'int');

            $content = $this->request->param('content', '', ['trim', 'htmlspecialchars']);
            if ($content == '') {
                throw new ApiException('请填写评价内容');
            }
            $userExamineRecordModel = new  UserEvaluateModel();
            $userExamineRecordModel->user_id = $userId;
            $userExamineRecordModel->coach_id = $coachId;
            $userExamineRecordModel->type = 0;
            $userExamineRecordModel->score = $score;
            $userExamineRecordModel->content = $content;
            $userExamineRecordModel->anonymity = $anonymity;
            $userExamineRecordModel->save();

            // 计算评分
            $list = UserEvaluateModel::where('type', 0)->where('coach_id', $coachId)->column('score');
            $count = count($list);
            $scoreTotal = array_sum($list);

            $avg = $count == 0 ? 0 : number_format($scoreTotal / $count, 1);

            if ($avg) {
                $coachInfo = UserPartnerModel::find($coachId);
                $coachInfo->score = $avg;
                $coachInfo->save();
            }

            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 值班列表
     * @return \think\response\Json
     */
    public function getDutyList()
    {
        try {
            $partnerId = $this->request->param('partner_id', 0);
            $dayString = $this->request->param('day', date('Y-m-d'), 'trim');

            $day = strtotime($dayString);

            $workTimeArr = ConfigService::getConfigValueArray(['work_time_start', 'work_time_end']);

            $startTime = $workTimeArr['work_time_start'];
            $endTime = $workTimeArr['work_time_end'];

            if (date('d', $day) == date('d')) {
                $currentTimestamp = time();
                $startTimestamp = strtotime(date('Y-m-d ') . $startTime . ':00');
                if ($currentTimestamp > $startTimestamp) {
                    $startTime = date('H', $currentTimestamp) + 1;
                }
            }

            $timeArr = PartnerBusyTimeModel::where('partner_id', $partnerId)
                ->where('day', $day)
                ->column('time');

            $list = [];
            $j = 0;
            for ($i = $startTime; $i <= $endTime; $i++) {
                if (in_array($i, $timeArr)) {
                    $isBusy = 1;
                } else {
                    $isBusy = 0;
                }
                $list[$j] = [
                    'time' => $i,
                    'type' => $isBusy
                ];
                $j++;
            }
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }
}